<?php
// +----------------------------------------------------------------------
// | ThinkPHP
// +----------------------------------------------------------------------
// | Copyright (c) 2008 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
// $Id$

/**
 +------------------------------------------------------------------------------
 * ThinkPHP 应用程序类 执行应用过程管理
 +------------------------------------------------------------------------------
 * @category   Think
 * @package  Think
 * @subpackage  Core
 * @author    liu21st <liu21st@gmail.com>
 * @version   $Id$
 +------------------------------------------------------------------------------
 */
class App extends Base
{//类定义开始

    /**
     +----------------------------------------------------------
     * 应用执行入口
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @return void
     +----------------------------------------------------------
     */
    static public function run()
    {
        // 检查项目是否编译过
        // 在部署模式下会自动在第一次执行的时候编译项目
        if(file_exists(RUNTIME_PATH.'~app.php') && (file_exists(CONFIG_PATH.'config.php') && filemtime(RUNTIME_PATH.'~app.php')>filemtime(CONFIG_PATH.'config.php'))) {
            // 直接读取编译后的项目文件
            C(include RUNTIME_PATH.'~app.php');
        }else{
            // 预编译项目
            self::build();
        }

        // 设置系统时区
        if(function_exists('date_default_timezone_set'))
            date_default_timezone_set(C('TIME_ZONE'));
        if(function_exists('spl_autoload_register')) {
            spl_autoload_register(array('Think', 'load'));
        }

        $showRunTime    =   C('SHOW_RUN_TIME');
        // 框架采用标签化管理和部署
        // 应用初始化标签
        Tag::apply('app_init');
        // 记录应用加载和初始化时间
        if($showRunTime)
            $GLOBALS['_initTime']   =   microtime(true);

        // 应用执行标签
        Tag::apply('app_run');
        // 记录应用执行时间
        if($showRunTime)
            $GLOBALS['_runTime']    =   microtime(true);

        // 应用结束标签
        Tag::apply('app_end');
        // 记录应用结束时间
        if($showRunTime)
            $GLOBALS['_endTime']    =   microtime(true);

        return ;
    }

    /**
     +----------------------------------------------------------
     * 读取配置信息 编译项目
     +----------------------------------------------------------
     * @access private
     +----------------------------------------------------------
     * @return string
     +----------------------------------------------------------
     */
    private static function build()
    {
        // 加载惯例配置文件
        C(array_change_key_case(include THINK_PATH.'/Common/convention.php'));

        // 加载项目配置文件
        if(file_exists(CONFIG_PATH.'config.php'))
            C(array_change_key_case(include CONFIG_PATH.'config.php'));

        // 加载项目标签文件
        // 定义格式 return array('init'=>array('filename1','filename2'),...)
        // 注意在标签文件中不要使用相对路径，否则缓存后会失效
        $debug  =   C('DEBUG_MODE');
        // 标签文件内容
        $tagContent =   '';
        if(file_exists(CONFIG_PATH.'tags.php')) {
            // 存在标签列表定义文件
            $tags    =   include CONFIG_PATH.'tags.php';
        }else{
            // 直接寻找项目标签文件
            $list   =   glob(TAGS_PATH.'*.php');
            if($list) {
                $find    =   true;
                foreach ($list as $key=>$file){
                    include $file;
                    if(!$debug) {
                        $tagContent .= php_strip_whitespace($file);
                    }
                }
            }else{
                // 没有任何标签文件，则调用框架默认的标签定义文件
                // 对于不熟悉框架的可以考虑使用内置的标签定义
                // 读取配置的系统默认标签方案
                $tags    =   include THINK_PATH.'/Common/tags_'.strtolower(C('DEFAULT_TAGS_STYLE')).'.php';
            }
        }

        // 依次导入标签文件
        if(is_array($tags) && empty($find)) {
            foreach ($tags as $tag=>$tagFile){
                foreach ($tagFile as $file){
                    $filename   =   file_exists($file)?$file:TAGS_PATH.$file;
                    include $filename;
                    if(!$debug) {
                        $tagContent .= php_strip_whitespace($filename);
                        if('?>' != substr($tagContent,-2)) {
                            $tagContent .= ' ?>';
                        }
                    }
                }
            }
        }

        if($debug) {
            // 调试模式
            // 加载系统默认的调试配置文件
            C(array_change_key_case(include THINK_PATH.'/Common/debug.php'));
            if(file_exists(CONFIG_PATH.'debug.php')) {
                // 项目调试模式配置定义
                C(array_change_key_case(include CONFIG_PATH.'debug.php'));
            }
        }else{
            // 部署模式下面生成编译文件
            $content  = $tagContent."<?php\nreturn ".var_export(C(),true).";\n?>";
            file_put_contents(RUNTIME_PATH.'~app.php',$content);
            if(defined('ENCODE_RUNTIME_FILE')) {
                // 压缩编译缓存文件
                encode_file_contents(RUNTIME_PATH.'~app.php');
            }
        }
        if(C('AUTO_SETUP_ON')) {
            // 开启项目自动安装支持
            if(file_exists(COMMON_PATH.'install.php') && !file_exists(APP_PATH.'install.ok')) {
                include COMMON_PATH.'install.php';
                file_put_contents(APP_PATH.'install.ok','install ok');
            }
        }
    }

    /**
     +----------------------------------------------------------
     * 停止应用
     +----------------------------------------------------------
     * @access public
     +----------------------------------------------------------
     * @return void
     +----------------------------------------------------------
     */
    static public function stop() {
        exit('App Stop');
    }
};//类定义结束
?>